package com.sojson.util.httpclient.impl;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import org.apache.http.NameValuePair;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpDelete;
import org.apache.http.client.methods.HttpEntityEnclosingRequestBase;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpPut;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;

import com.sojson.constant.Constant;
import com.sojson.util.StringUtil;
import com.sojson.util.httpclient.HttpClientUtil;
import com.sojson.util.httpclient.HttpClientUtilInterface;
import com.sojson.util.json.JsonUtil;

/**
 * HttpClient工具类实现类
 * 
 * @author liu
 * @Date 2020-06-15 14:45:16
 * @Description
 *
 */
public class HttpClientUtilImpl implements HttpClientUtilInterface {

    private static HttpClientUtilImpl httpClientUtilsImpl;
    /**
     * setConnectTimeout:设置连接超时时间，单位毫秒。 setConnectionRequestTimeout:设置从connect
     * Manager(连接池)获取Connection 超时时间，单位毫秒。这个属性是新加的属性，因为目前版本是可以共享连接池的。
     * setSocketTimeout:请求获取数据的超时时间(即响应时间)，单位毫秒。 如果访问一个接口，多少时间内无法返回数据，就直接放弃此次调用。
     */
    private RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(HttpClientUtil.connectTimeout)
        .setSocketTimeout(HttpClientUtil.socketTimeout).build();

    private HttpClientUtilImpl() {}

    /**
     * 发送get请求
     * 
     * @param url 地址
     * @return
     * @throws Exception
     */
    @Override
    public String doGet(String url) throws Exception {
        // 创建httpClient对象
        CloseableHttpClient httpClient = HttpClients.createDefault();

        // 创建访问的地址
        URIBuilder uriBuilder = new URIBuilder(url);

        // 创建http对象
        HttpGet httpGet = new HttpGet(uriBuilder.build());
        httpGet.setConfig(requestConfig);

        // 创建httpResponse对象
        CloseableHttpResponse httpResponse = null;
        try {
            // 执行请求并获得响应结果
            return getHttpClientResult(httpResponse, httpClient, httpGet);
        } finally {
            // 释放资源
            release(httpResponse, httpClient);
        }
    }

    /**
     * 发送get请求
     * 
     * @param url 地址
     * @param headers 请求头(Json数据格式)
     * @return
     * @throws Exception
     */
    @Override
    public String doGetByHeader(String url, String headers) throws Exception {
        // 创建httpClient对象
        CloseableHttpClient httpClient = HttpClients.createDefault();

        // 创建访问的地址
        URIBuilder uriBuilder = new URIBuilder(url);

        // 创建http对象
        HttpGet httpGet = new HttpGet(uriBuilder.build());
        httpGet.setConfig(requestConfig);
        // 设置请求头
        setHeader(httpGet, headers);

        // 创建httpResponse对象
        CloseableHttpResponse httpResponse = null;
        try {
            // 执行请求并获得响应结果
            return getHttpClientResult(httpResponse, httpClient, httpGet);
        } finally {
            // 释放资源
            release(httpResponse, httpClient);
        }
    }

    /**
     * 发送get请求
     * 
     * @param url 地址
     * @param headers 请求头
     * @return
     * @throws Exception
     */
    @Override
    public String doGetByHeader(String url, Map<String, String> headers) throws Exception {
        // 创建httpClient对象
        CloseableHttpClient httpClient = HttpClients.createDefault();

        // 创建访问的地址
        URIBuilder uriBuilder = new URIBuilder(url);

        // 创建http对象
        HttpGet httpGet = new HttpGet(uriBuilder.build());
        httpGet.setConfig(requestConfig);
        // 设置请求头
        setHeader(httpGet, headers);

        // 创建httpResponse对象
        CloseableHttpResponse httpResponse = null;
        try {
            // 执行请求并获得响应结果
            return getHttpClientResult(httpResponse, httpClient, httpGet);
        } finally {
            // 释放资源
            release(httpResponse, httpClient);
        }
    }

    /**
     * 发送get请求
     * 
     * @param url 地址
     * @param params 参数(Json数据格式)
     * @return
     * @throws Exception
     */
    @Override
    public String doGetByParam(String url, String params) throws Exception {
        // 创建httpClient对象
        CloseableHttpClient httpClient = HttpClients.createDefault();

        // 创建访问的地址
        URIBuilder uriBuilder = new URIBuilder(url);
        setParam(uriBuilder, params);

        // 创建http对象
        HttpGet httpGet = new HttpGet(uriBuilder.build());
        httpGet.setConfig(requestConfig);

        // 创建httpResponse对象
        CloseableHttpResponse httpResponse = null;
        try {
            // 执行请求并获得响应结果
            return getHttpClientResult(httpResponse, httpClient, httpGet);
        } finally {
            // 释放资源
            release(httpResponse, httpClient);
        }
    }

    /**
     * 发送get请求
     * 
     * @param url 地址
     * @param params 参数
     * @return
     * @throws Exception
     */
    @Override
    public String doGetByParam(String url, Map<String, String> params) throws Exception {
        // 创建httpClient对象
        CloseableHttpClient httpClient = HttpClients.createDefault();

        // 创建访问的地址
        URIBuilder uriBuilder = new URIBuilder(url);
        setParam(uriBuilder, params);

        // 创建http对象
        HttpGet httpGet = new HttpGet(uriBuilder.build());
        httpGet.setConfig(requestConfig);

        // 创建httpResponse对象
        CloseableHttpResponse httpResponse = null;
        try {
            // 执行请求并获得响应结果
            return getHttpClientResult(httpResponse, httpClient, httpGet);
        } finally {
            // 释放资源
            release(httpResponse, httpClient);
        }
    }

    /**
     * 发送get请求
     * 
     * @param url 地址
     * @param headers 请求头(Json数据格式)
     * @param params 参数(Json数据格式)
     * @return
     * @throws Exception
     */
    @Override
    public String doGet(String url, String headers, String params) throws Exception {
        // 创建httpClient对象
        CloseableHttpClient httpClient = HttpClients.createDefault();

        // 创建访问的地址
        URIBuilder uriBuilder = new URIBuilder(url);
        setParam(uriBuilder, params);

        // 创建http对象
        HttpGet httpGet = new HttpGet(uriBuilder.build());
        httpGet.setConfig(requestConfig);
        // 设置请求头
        setHeader(httpGet, headers);

        // 创建httpResponse对象
        CloseableHttpResponse httpResponse = null;
        try {
            // 执行请求并获得响应结果
            return getHttpClientResult(httpResponse, httpClient, httpGet);
        } finally {
            // 释放资源
            release(httpResponse, httpClient);
        }
    }

    /**
     * 发送get请求
     * 
     * @param url 地址
     * @param headers 请求头
     * @param params 参数(Json数据格式)
     * @return
     * @throws Exception
     */
    @Override
    public String doGet(String url, Map<String, String> headers, String params) throws Exception {
        // 创建httpClient对象
        CloseableHttpClient httpClient = HttpClients.createDefault();

        // 创建访问的地址
        URIBuilder uriBuilder = new URIBuilder(url);
        setParam(uriBuilder, params);

        // 创建http对象
        HttpGet httpGet = new HttpGet(uriBuilder.build());
        httpGet.setConfig(requestConfig);
        // 设置请求头
        setHeader(httpGet, headers);

        // 创建httpResponse对象
        CloseableHttpResponse httpResponse = null;
        try {
            // 执行请求并获得响应结果
            return getHttpClientResult(httpResponse, httpClient, httpGet);
        } finally {
            // 释放资源
            release(httpResponse, httpClient);
        }
    }

    /**
     * 发送get请求
     * 
     * @param url 地址
     * @param headers 请求头(Json数据格式)
     * @param params 参数
     * @return
     * @throws Exception
     */
    @Override
    public String doGet(String url, String headers, Map<String, String> params) throws Exception {
        // 创建httpClient对象
        CloseableHttpClient httpClient = HttpClients.createDefault();

        // 创建访问的地址
        URIBuilder uriBuilder = new URIBuilder(url);
        setParam(uriBuilder, params);

        // 创建http对象
        HttpGet httpGet = new HttpGet(uriBuilder.build());
        httpGet.setConfig(requestConfig);
        // 设置请求头
        setHeader(httpGet, headers);

        // 创建httpResponse对象
        CloseableHttpResponse httpResponse = null;
        try {
            // 执行请求并获得响应结果
            return getHttpClientResult(httpResponse, httpClient, httpGet);
        } finally {
            // 释放资源
            release(httpResponse, httpClient);
        }
    }

    /**
     * 发送get请求
     * 
     * @param url 地址
     * @param headers 请求头
     * @param params 参数
     * @return
     * @throws Exception
     */
    @Override
    public String doGet(String url, Map<String, String> headers, Map<String, String> params) throws Exception {
        // 创建httpClient对象
        CloseableHttpClient httpClient = HttpClients.createDefault();

        // 创建访问的地址
        URIBuilder uriBuilder = new URIBuilder(url);
        setParam(uriBuilder, params);

        // 创建http对象
        HttpGet httpGet = new HttpGet(uriBuilder.build());
        httpGet.setConfig(requestConfig);
        // 设置请求头
        setHeader(httpGet, headers);

        // 创建httpResponse对象
        CloseableHttpResponse httpResponse = null;
        try {
            // 执行请求并获得响应结果
            return getHttpClientResult(httpResponse, httpClient, httpGet);
        } finally {
            // 释放资源
            release(httpResponse, httpClient);
        }
    }

    /**
     * 发送post请求
     * 
     * @param url 地址
     * @return
     * @throws IOException
     */
    @Override
    public String doPost(String url) throws IOException {
        // 创建httpClient对象
        CloseableHttpClient httpClient = HttpClients.createDefault();

        // 创建http对象
        HttpPost httpPost = new HttpPost(url);
        httpPost.setConfig(requestConfig);

        // 创建httpResponse对象
        CloseableHttpResponse httpResponse = null;
        try {
            // 执行请求并获得响应结果
            return getHttpClientResult(httpResponse, httpClient, httpPost);
        } finally {
            // 释放资源
            release(httpResponse, httpClient);
        }
    }

    /**
     * 发送post请求
     * 
     * @param url 地址
     * @param headers 请求头(Json数据格式)
     * @return
     * @throws IOException
     */
    @Override
    public String doPostByHeader(String url, String headers) throws IOException {
        // 创建httpClient对象
        CloseableHttpClient httpClient = HttpClients.createDefault();

        // 创建http对象
        HttpPost httpPost = new HttpPost(url);
        httpPost.setConfig(requestConfig);
        // 设置请求头
        setHeader(httpPost, headers);

        // 创建httpResponse对象
        CloseableHttpResponse httpResponse = null;
        try {
            // 执行请求并获得响应结果
            return getHttpClientResult(httpResponse, httpClient, httpPost);
        } finally {
            // 释放资源
            release(httpResponse, httpClient);
        }
    }

    /**
     * 发送post请求
     * 
     * @param url 地址
     * @param headers 请求头
     * @return
     * @throws IOException
     */
    @Override
    public String doPostByHeader(String url, Map<String, String> headers) throws IOException {
        // 创建httpClient对象
        CloseableHttpClient httpClient = HttpClients.createDefault();

        // 创建http对象
        HttpPost httpPost = new HttpPost(url);
        httpPost.setConfig(requestConfig);
        // 设置请求头
        setHeader(httpPost, headers);

        // 创建httpResponse对象
        CloseableHttpResponse httpResponse = null;
        try {
            // 执行请求并获得响应结果
            return getHttpClientResult(httpResponse, httpClient, httpPost);
        } finally {
            // 释放资源
            release(httpResponse, httpClient);
        }
    }

    /**
     * 发送post请求
     * 
     * @param url 地址
     * @param params 参数(Json数据格式)
     * @return
     * @throws IOException
     */
    @Override
    public String doPostByParam(String url, String params) throws IOException {
        // 创建httpClient对象
        CloseableHttpClient httpClient = HttpClients.createDefault();

        // 创建http对象
        HttpPost httpPost = new HttpPost(url);
        httpPost.setConfig(requestConfig);

        // 设置参数
        setParam(httpPost, params);

        // 创建httpResponse对象
        CloseableHttpResponse httpResponse = null;
        try {
            // 执行请求并获得响应结果
            return getHttpClientResult(httpResponse, httpClient, httpPost);
        } finally {
            // 释放资源
            release(httpResponse, httpClient);
        }
    }

    /**
     * 发送post请求
     * 
     * @param url 地址
     * @param params 参数
     * @return
     * @throws IOException
     */
    @Override
    public String doPostByParam(String url, Map<String, String> params) throws IOException {
        // 创建httpClient对象
        CloseableHttpClient httpClient = HttpClients.createDefault();

        // 创建http对象
        HttpPost httpPost = new HttpPost(url);
        httpPost.setConfig(requestConfig);

        // 设置参数
        setParam(httpPost, params);

        // 创建httpResponse对象
        CloseableHttpResponse httpResponse = null;
        try {
            // 执行请求并获得响应结果
            return getHttpClientResult(httpResponse, httpClient, httpPost);
        } finally {
            // 释放资源
            release(httpResponse, httpClient);
        }
    }

    /**
     * 发送post请求
     * 
     * @param url 地址
     * @param headers 请求头(Json数据格式)
     * @param params 参数(Json数据格式)
     * @return
     * @throws IOException
     */
    @Override
    public String doPost(String url, String headers, String params) throws IOException {
        // 创建httpClient对象
        CloseableHttpClient httpClient = HttpClients.createDefault();

        // 创建http对象
        HttpPost httpPost = new HttpPost(url);
        httpPost.setConfig(requestConfig);
        // 设置请求头
        setHeader(httpPost, headers);

        // 设置参数
        setParam(httpPost, params);

        // 创建httpResponse对象
        CloseableHttpResponse httpResponse = null;
        try {
            // 执行请求并获得响应结果
            return getHttpClientResult(httpResponse, httpClient, httpPost);
        } finally {
            // 释放资源
            release(httpResponse, httpClient);
        }
    }

    /**
     * 发送post请求
     * 
     * @param url 地址
     * @param headers 请求头
     * @param params 参数(Json数据格式)
     * @return
     * @throws IOException
     */
    @Override
    public String doPost(String url, Map<String, String> headers, String params) throws IOException {
        // 创建httpClient对象
        CloseableHttpClient httpClient = HttpClients.createDefault();

        // 创建http对象
        HttpPost httpPost = new HttpPost(url);
        httpPost.setConfig(requestConfig);
        // 设置请求头
        setHeader(httpPost, headers);

        // 设置参数
        setParam(httpPost, params);

        // 创建httpResponse对象
        CloseableHttpResponse httpResponse = null;
        try {
            // 执行请求并获得响应结果
            return getHttpClientResult(httpResponse, httpClient, httpPost);
        } finally {
            // 释放资源
            release(httpResponse, httpClient);
        }
    }

    /**
     * 发送post请求
     * 
     * @param url 地址
     * @param headers 请求头(Json数据格式)
     * @param params 参数
     * @return
     * @throws IOException
     */
    @Override
    public String doPost(String url, String headers, Map<String, String> params) throws IOException {
        // 创建httpClient对象
        CloseableHttpClient httpClient = HttpClients.createDefault();

        // 创建http对象
        HttpPost httpPost = new HttpPost(url);
        httpPost.setConfig(requestConfig);
        // 设置请求头
        setHeader(httpPost, headers);

        // 设置参数
        setParam(httpPost, params);

        // 创建httpResponse对象
        CloseableHttpResponse httpResponse = null;
        try {
            // 执行请求并获得响应结果
            return getHttpClientResult(httpResponse, httpClient, httpPost);
        } finally {
            // 释放资源
            release(httpResponse, httpClient);
        }
    }

    /**
     * 发送post请求
     * 
     * @param url 地址
     * @param headers 请求头
     * @param params 参数
     * @return
     * @throws IOException
     */
    @Override
    public String doPost(String url, Map<String, String> headers, Map<String, String> params) throws IOException {
        // 创建httpClient对象
        CloseableHttpClient httpClient = HttpClients.createDefault();

        // 创建http对象
        HttpPost httpPost = new HttpPost(url);
        httpPost.setConfig(requestConfig);
        // 设置请求头
        setHeader(httpPost, headers);

        // 设置参数
        setParam(httpPost, params);

        // 创建httpResponse对象
        CloseableHttpResponse httpResponse = null;
        try {
            // 执行请求并获得响应结果
            return getHttpClientResult(httpResponse, httpClient, httpPost);
        } finally {
            // 释放资源
            release(httpResponse, httpClient);
        }
    }

    /**
     * 发送put请求
     * 
     * @param url 地址
     * @return
     * @throws IOException
     */
    @Override
    public String doPut(String url) throws IOException {
        CloseableHttpClient httpClient = HttpClients.createDefault();
        HttpPut httpPut = new HttpPut(url);

        httpPut.setConfig(requestConfig);

        CloseableHttpResponse httpResponse = null;

        try {
            return getHttpClientResult(httpResponse, httpClient, httpPut);
        } finally {
            release(httpResponse, httpClient);
        }
    }

    /**
     * 发送put请求
     * 
     * @param url 地址
     * @param params 参数
     * @return
     * @throws IOException
     */
    @Override
    public String doPut(String url, Map<String, String> params) throws IOException {
        CloseableHttpClient httpClient = HttpClients.createDefault();
        HttpPut httpPut = new HttpPut(url);

        httpPut.setConfig(requestConfig);

        setParam(httpPut, params);

        CloseableHttpResponse httpResponse = null;

        try {
            return getHttpClientResult(httpResponse, httpClient, httpPut);
        } finally {
            release(httpResponse, httpClient);
        }
    }

    /**
     * 发送delete请求
     * 
     * @param url 地址
     * @param params 参数
     * @return
     * @throws IOException
     */
    @Override
    public String doDelete(String url) throws IOException {
        CloseableHttpClient httpClient = HttpClients.createDefault();
        HttpDelete httpDelete = new HttpDelete(url);

        httpDelete.setConfig(requestConfig);

        CloseableHttpResponse httpResponse = null;
        try {
            return getHttpClientResult(httpResponse, httpClient, httpDelete);
        } finally {
            release(httpResponse, httpClient);
        }
    }

    /**
     * 发送delete请求
     * 
     * @param url 地址
     * @param params 参数
     * @return
     * @throws IOException
     */
    @Override
    public String doDelete(String url, Map<String, String> params) throws IOException {
        if (isBlankObject(params)) {
            params = new HashMap<>(5);
        }

        params.put("_method", "delete");
        return doPostByParam(url, params);
    }

    /**
     * 发送get请求
     * 
     * @param url 地址
     * @return
     * @throws Exception
     */
    @Override
    public byte[] doGetByte(String url) throws Exception {
        // 创建httpClient对象
        CloseableHttpClient httpClient = HttpClients.createDefault();

        // 创建访问的地址
        URIBuilder uriBuilder = new URIBuilder(url);

        // 创建http对象
        HttpGet httpGet = new HttpGet(uriBuilder.build());
        httpGet.setConfig(requestConfig);

        // 创建httpResponse对象
        CloseableHttpResponse httpResponse = null;
        try {
            // 执行请求并获得响应结果
            return getHttpClientByteResult(httpResponse, httpClient, httpGet);
        } finally {
            // 释放资源
            release(httpResponse, httpClient);
        }
    }

    /**
     * 发送get请求
     * 
     * @param url 地址
     * @param headers 请求头(Json数据格式)
     * @return
     * @throws Exception
     */
    @Override
    public byte[] doGetByteByHeader(String url, String headers) throws Exception {
        // 创建httpClient对象
        CloseableHttpClient httpClient = HttpClients.createDefault();

        // 创建访问的地址
        URIBuilder uriBuilder = new URIBuilder(url);

        // 创建http对象
        HttpGet httpGet = new HttpGet(uriBuilder.build());
        httpGet.setConfig(requestConfig);
        // 设置请求头
        setHeader(httpGet, headers);

        // 创建httpResponse对象
        CloseableHttpResponse httpResponse = null;
        try {
            // 执行请求并获得响应结果
            return getHttpClientByteResult(httpResponse, httpClient, httpGet);
        } finally {
            // 释放资源
            release(httpResponse, httpClient);
        }
    }

    /**
     * 发送get请求
     * 
     * @param url 地址
     * @param headers 请求头
     * @return
     * @throws Exception
     */
    @Override
    public byte[] doGetByteByHeader(String url, Map<String, String> headers) throws Exception {
        // 创建httpClient对象
        CloseableHttpClient httpClient = HttpClients.createDefault();

        // 创建访问的地址
        URIBuilder uriBuilder = new URIBuilder(url);

        // 创建http对象
        HttpGet httpGet = new HttpGet(uriBuilder.build());
        httpGet.setConfig(requestConfig);
        // 设置请求头
        setHeader(httpGet, headers);

        // 创建httpResponse对象
        CloseableHttpResponse httpResponse = null;
        try {
            // 执行请求并获得响应结果
            return getHttpClientByteResult(httpResponse, httpClient, httpGet);
        } finally {
            // 释放资源
            release(httpResponse, httpClient);
        }
    }

    /**
     * 发送get请求
     * 
     * @param url 地址
     * @param params 参数(Json数据格式)
     * @return
     * @throws Exception
     */
    @Override
    public byte[] doGetByteByParam(String url, String params) throws Exception {
        // 创建httpClient对象
        CloseableHttpClient httpClient = HttpClients.createDefault();

        // 创建访问的地址
        URIBuilder uriBuilder = new URIBuilder(url);
        setParam(uriBuilder, params);

        // 创建http对象
        HttpGet httpGet = new HttpGet(uriBuilder.build());
        httpGet.setConfig(requestConfig);

        // 创建httpResponse对象
        CloseableHttpResponse httpResponse = null;
        try {
            // 执行请求并获得响应结果
            return getHttpClientByteResult(httpResponse, httpClient, httpGet);
        } finally {
            // 释放资源
            release(httpResponse, httpClient);
        }
    }

    /**
     * 发送get请求
     * 
     * @param url 地址
     * @param params 参数
     * @return
     * @throws Exception
     */
    @Override
    public byte[] doGetByteByParam(String url, Map<String, String> params) throws Exception {
        // 创建httpClient对象
        CloseableHttpClient httpClient = HttpClients.createDefault();

        // 创建访问的地址
        URIBuilder uriBuilder = new URIBuilder(url);
        setParam(uriBuilder, params);

        // 创建http对象
        HttpGet httpGet = new HttpGet(uriBuilder.build());
        httpGet.setConfig(requestConfig);

        // 创建httpResponse对象
        CloseableHttpResponse httpResponse = null;
        try {
            // 执行请求并获得响应结果
            return getHttpClientByteResult(httpResponse, httpClient, httpGet);
        } finally {
            // 释放资源
            release(httpResponse, httpClient);
        }
    }

    /**
     * 发送get请求
     * 
     * @param url 地址
     * @param headers 请求头(Json数据格式)
     * @param params 参数(Json数据格式)
     * @return
     * @throws Exception
     */
    @Override
    public byte[] doGetByte(String url, String headers, String params) throws Exception {
        // 创建httpClient对象
        CloseableHttpClient httpClient = HttpClients.createDefault();

        // 创建访问的地址
        URIBuilder uriBuilder = new URIBuilder(url);
        setParam(uriBuilder, params);

        // 创建http对象
        HttpGet httpGet = new HttpGet(uriBuilder.build());
        httpGet.setConfig(requestConfig);
        // 设置请求头
        setHeader(httpGet, headers);

        // 创建httpResponse对象
        CloseableHttpResponse httpResponse = null;
        try {
            // 执行请求并获得响应结果
            return getHttpClientByteResult(httpResponse, httpClient, httpGet);
        } finally {
            // 释放资源
            release(httpResponse, httpClient);
        }
    }

    /**
     * 发送get请求
     * 
     * @param url 地址
     * @param headers 请求头
     * @param params 参数(Json数据格式)
     * @return
     * @throws Exception
     */
    @Override
    public byte[] doGetByte(String url, Map<String, String> headers, String params) throws Exception {
        // 创建httpClient对象
        CloseableHttpClient httpClient = HttpClients.createDefault();

        // 创建访问的地址
        URIBuilder uriBuilder = new URIBuilder(url);
        setParam(uriBuilder, params);

        // 创建http对象
        HttpGet httpGet = new HttpGet(uriBuilder.build());
        httpGet.setConfig(requestConfig);
        // 设置请求头
        setHeader(httpGet, headers);

        // 创建httpResponse对象
        CloseableHttpResponse httpResponse = null;
        try {
            // 执行请求并获得响应结果
            return getHttpClientByteResult(httpResponse, httpClient, httpGet);
        } finally {
            // 释放资源
            release(httpResponse, httpClient);
        }
    }

    /**
     * 发送get请求
     * 
     * @param url 地址
     * @param headers 请求头(Json数据格式)
     * @param params 参数
     * @return
     * @throws Exception
     */
    @Override
    public byte[] doGetByte(String url, String headers, Map<String, String> params) throws Exception {
        // 创建httpClient对象
        CloseableHttpClient httpClient = HttpClients.createDefault();

        // 创建访问的地址
        URIBuilder uriBuilder = new URIBuilder(url);
        setParam(uriBuilder, params);

        // 创建http对象
        HttpGet httpGet = new HttpGet(uriBuilder.build());
        httpGet.setConfig(requestConfig);
        // 设置请求头
        setHeader(httpGet, headers);

        // 创建httpResponse对象
        CloseableHttpResponse httpResponse = null;
        try {
            // 执行请求并获得响应结果
            return getHttpClientByteResult(httpResponse, httpClient, httpGet);
        } finally {
            // 释放资源
            release(httpResponse, httpClient);
        }
    }

    /**
     * 发送get请求
     * 
     * @param url 地址
     * @param headers 请求头
     * @param params 参数
     * @return
     * @throws Exception
     */
    @Override
    public byte[] doGetByte(String url, Map<String, String> headers, Map<String, String> params) throws Exception {
        // 创建httpClient对象
        CloseableHttpClient httpClient = HttpClients.createDefault();

        // 创建访问的地址
        URIBuilder uriBuilder = new URIBuilder(url);
        setParam(uriBuilder, params);

        // 创建http对象
        HttpGet httpGet = new HttpGet(uriBuilder.build());
        httpGet.setConfig(requestConfig);
        // 设置请求头
        setHeader(httpGet, headers);

        // 创建httpResponse对象
        CloseableHttpResponse httpResponse = null;
        try {
            // 执行请求并获得响应结果
            return getHttpClientByteResult(httpResponse, httpClient, httpGet);
        } finally {
            // 释放资源
            release(httpResponse, httpClient);
        }
    }

    /**
     * 发送post请求
     * 
     * @param url 地址
     * @return
     * @throws IOException
     */
    @Override
    public byte[] doPostByte(String url) throws IOException {
        // 创建httpClient对象
        CloseableHttpClient httpClient = HttpClients.createDefault();

        // 创建http对象
        HttpPost httpPost = new HttpPost(url);
        httpPost.setConfig(requestConfig);

        // 创建httpResponse对象
        CloseableHttpResponse httpResponse = null;
        try {
            // 执行请求并获得响应结果
            return getHttpClientByteResult(httpResponse, httpClient, httpPost);
        } finally {
            // 释放资源
            release(httpResponse, httpClient);
        }
    }

    /**
     * 发送post请求
     * 
     * @param url 地址
     * @param headers 请求头(Json数据格式)
     * @return
     * @throws IOException
     */
    @Override
    public byte[] doPostByteByHeader(String url, String headers) throws IOException {
        // 创建httpClient对象
        CloseableHttpClient httpClient = HttpClients.createDefault();

        // 创建http对象
        HttpPost httpPost = new HttpPost(url);
        httpPost.setConfig(requestConfig);
        // 设置请求头
        setHeader(httpPost, headers);

        // 创建httpResponse对象
        CloseableHttpResponse httpResponse = null;
        try {
            // 执行请求并获得响应结果
            return getHttpClientByteResult(httpResponse, httpClient, httpPost);
        } finally {
            // 释放资源
            release(httpResponse, httpClient);
        }
    }

    /**
     * 发送post请求
     * 
     * @param url 地址
     * @param headers 请求头
     * @return
     * @throws IOException
     */
    @Override
    public byte[] doPostByteByHeader(String url, Map<String, String> headers) throws IOException {
        // 创建httpClient对象
        CloseableHttpClient httpClient = HttpClients.createDefault();

        // 创建http对象
        HttpPost httpPost = new HttpPost(url);
        httpPost.setConfig(requestConfig);
        // 设置请求头
        setHeader(httpPost, headers);

        // 创建httpResponse对象
        CloseableHttpResponse httpResponse = null;
        try {
            // 执行请求并获得响应结果
            return getHttpClientByteResult(httpResponse, httpClient, httpPost);
        } finally {
            // 释放资源
            release(httpResponse, httpClient);
        }
    }

    /**
     * 发送post请求
     * 
     * @param url 地址
     * @param params 参数(Json数据格式)
     * @return
     * @throws IOException
     */
    @Override
    public byte[] doPostByteByParam(String url, String params) throws IOException {
        // 创建httpClient对象
        CloseableHttpClient httpClient = HttpClients.createDefault();

        // 创建http对象
        HttpPost httpPost = new HttpPost(url);
        httpPost.setConfig(requestConfig);

        // 设置参数
        setParam(httpPost, params);

        // 创建httpResponse对象
        CloseableHttpResponse httpResponse = null;
        try {
            // 执行请求并获得响应结果
            return getHttpClientByteResult(httpResponse, httpClient, httpPost);
        } finally {
            // 释放资源
            release(httpResponse, httpClient);
        }
    }

    /**
     * 发送post请求
     * 
     * @param url 地址
     * @param params 参数
     * @return
     * @throws IOException
     */
    @Override
    public byte[] doPostByteByParam(String url, Map<String, String> params) throws IOException {
        // 创建httpClient对象
        CloseableHttpClient httpClient = HttpClients.createDefault();

        // 创建http对象
        HttpPost httpPost = new HttpPost(url);
        httpPost.setConfig(requestConfig);

        // 设置参数
        setParam(httpPost, params);

        // 创建httpResponse对象
        CloseableHttpResponse httpResponse = null;
        try {
            // 执行请求并获得响应结果
            return getHttpClientByteResult(httpResponse, httpClient, httpPost);
        } finally {
            // 释放资源
            release(httpResponse, httpClient);
        }
    }

    /**
     * 发送post请求
     * 
     * @param url 地址
     * @param headers 请求头(Json数据格式)
     * @param params 参数(Json数据格式)
     * @return
     * @throws IOException
     */
    @Override
    public byte[] doPostByte(String url, String headers, String params) throws IOException {
        // 创建httpClient对象
        CloseableHttpClient httpClient = HttpClients.createDefault();

        // 创建http对象
        HttpPost httpPost = new HttpPost(url);
        httpPost.setConfig(requestConfig);
        // 设置请求头
        setHeader(httpPost, headers);

        // 设置参数
        setParam(httpPost, params);

        // 创建httpResponse对象
        CloseableHttpResponse httpResponse = null;
        try {
            // 执行请求并获得响应结果
            return getHttpClientByteResult(httpResponse, httpClient, httpPost);
        } finally {
            // 释放资源
            release(httpResponse, httpClient);
        }
    }

    /**
     * 发送post请求
     * 
     * @param url 地址
     * @param headers 请求头
     * @param params 参数(Json数据格式)
     * @return
     * @throws IOException
     */
    @Override
    public byte[] doPostByte(String url, Map<String, String> headers, String params) throws IOException {
        // 创建httpClient对象
        CloseableHttpClient httpClient = HttpClients.createDefault();

        // 创建http对象
        HttpPost httpPost = new HttpPost(url);
        httpPost.setConfig(requestConfig);
        // 设置请求头
        setHeader(httpPost, headers);

        // 设置参数
        setParam(httpPost, params);

        // 创建httpResponse对象
        CloseableHttpResponse httpResponse = null;
        try {
            // 执行请求并获得响应结果
            return getHttpClientByteResult(httpResponse, httpClient, httpPost);
        } finally {
            // 释放资源
            release(httpResponse, httpClient);
        }
    }

    /**
     * 发送post请求
     * 
     * @param url 地址
     * @param headers 请求头(Json数据格式)
     * @param params 参数
     * @return
     * @throws IOException
     */
    @Override
    public byte[] doPostByte(String url, String headers, Map<String, String> params) throws IOException {
        // 创建httpClient对象
        CloseableHttpClient httpClient = HttpClients.createDefault();

        // 创建http对象
        HttpPost httpPost = new HttpPost(url);
        httpPost.setConfig(requestConfig);
        // 设置请求头
        setHeader(httpPost, headers);

        // 设置参数
        setParam(httpPost, params);

        // 创建httpResponse对象
        CloseableHttpResponse httpResponse = null;
        try {
            // 执行请求并获得响应结果
            return getHttpClientByteResult(httpResponse, httpClient, httpPost);
        } finally {
            // 释放资源
            release(httpResponse, httpClient);
        }
    }

    /**
     * 发送post请求
     * 
     * @param url 地址
     * @param headers 请求头
     * @param params 参数
     * @return
     * @throws IOException
     */
    @Override
    public byte[] doPostByte(String url, Map<String, String> headers, Map<String, String> params) throws IOException {
        // 创建httpClient对象
        CloseableHttpClient httpClient = HttpClients.createDefault();

        // 创建http对象
        HttpPost httpPost = new HttpPost(url);
        httpPost.setConfig(requestConfig);
        // 设置请求头
        setHeader(httpPost, headers);

        // 设置参数
        setParam(httpPost, params);

        // 创建httpResponse对象
        CloseableHttpResponse httpResponse = null;
        try {
            // 执行请求并获得响应结果
            return getHttpClientByteResult(httpResponse, httpClient, httpPost);
        } finally {
            // 释放资源
            release(httpResponse, httpClient);
        }
    }

    /**
     * 发送put请求
     * 
     * @param url 地址
     * @return
     * @throws IOException
     */
    @Override
    public byte[] doPutByte(String url) throws IOException {
        CloseableHttpClient httpClient = HttpClients.createDefault();
        HttpPut httpPut = new HttpPut(url);

        httpPut.setConfig(requestConfig);

        CloseableHttpResponse httpResponse = null;

        try {
            return getHttpClientByteResult(httpResponse, httpClient, httpPut);
        } finally {
            release(httpResponse, httpClient);
        }
    }

    /**
     * 发送put请求
     * 
     * @param url 地址
     * @param params 参数
     * @return
     * @throws IOException
     */
    @Override
    public byte[] doPutByte(String url, Map<String, String> params) throws IOException {
        CloseableHttpClient httpClient = HttpClients.createDefault();
        HttpPut httpPut = new HttpPut(url);

        httpPut.setConfig(requestConfig);

        setParam(httpPut, params);

        CloseableHttpResponse httpResponse = null;

        try {
            return getHttpClientByteResult(httpResponse, httpClient, httpPut);
        } finally {
            release(httpResponse, httpClient);
        }
    }

    /**
     * 发送delete请求
     * 
     * @param url 地址
     * @param params 参数
     * @return
     * @throws IOException
     */
    @Override
    public byte[] doDeleteByte(String url) throws IOException {
        CloseableHttpClient httpClient = HttpClients.createDefault();
        HttpDelete httpDelete = new HttpDelete(url);

        httpDelete.setConfig(requestConfig);

        CloseableHttpResponse httpResponse = null;
        try {
            return getHttpClientByteResult(httpResponse, httpClient, httpDelete);
        } finally {
            release(httpResponse, httpClient);
        }
    }

    /**
     * 发送delete请求
     * 
     * @param url 地址
     * @param params 参数
     * @return
     * @throws IOException
     */
    @Override
    public byte[] doDeleteByte(String url, Map<String, String> params) throws IOException {
        if (isBlankObject(params)) {
            params = new HashMap<>(5);
        }

        params.put("_method", "delete");
        return doPostByteByParam(url, params);
    }

    /**
     * Description: 封装请求头
     * 
     * @param httpMethod
     * @param headers 请求头
     */
    private void setHeader(HttpRequestBase httpMethod, String headers) {
        // 封装请求头
        if (isNotBlankObject(headers)) {
            Map<String, String> jsonToMap = JsonUtil.jsonToMap(headers, String.class, String.class);
            for (Entry<String, String> entry : jsonToMap.entrySet()) {
                // 设置到请求头到HttpRequestBase对象中
                httpMethod.setHeader(entry.getKey(), entry.getValue());
            }
        }
    }

    /**
     * Description: 封装请求头
     * 
     * @param httpMethod
     * @param headers 请求头
     */
    private void setHeader(HttpRequestBase httpMethod, Map<String, String> headers) {
        // 封装请求头
        if (isNotBlankObject(headers)) {
            for (Entry<String, String> entry : headers.entrySet()) {
                // 设置到请求头到HttpRequestBase对象中
                httpMethod.setHeader(entry.getKey(), entry.getValue());
            }
        }
    }

    /**
     * Description: 设置参数
     * 
     * @param uriBuilder
     * @param params 参数
     */
    private void setParam(URIBuilder uriBuilder, String params) {
        // 设置参数
        if (isNotBlankObject(params)) {
            Map<String, String> jsonToMap = JsonUtil.jsonToMap(params, String.class, String.class);
            for (Entry<String, String> entry : jsonToMap.entrySet()) {
                uriBuilder.setParameter(entry.getKey(), String.valueOf(entry.getValue()));
            }
        }
    }

    /**
     * Description: 设置参数
     * 
     * @param uriBuilder
     * @param params 参数
     */
    private void setParam(URIBuilder uriBuilder, Map<String, String> params) {
        // 设置参数
        if (isNotBlankObject(params)) {
            Set<Entry<String, String>> entrySet = params.entrySet();
            for (Entry<String, String> entry : entrySet) {
                uriBuilder.setParameter(entry.getKey(), entry.getValue());
            }
        }
    }

    /**
     * Description: 设置参数
     * 
     * @param httpMethod
     * @param params 参数
     * @throws IOException 
     */
    private void setParam(HttpEntityEnclosingRequestBase httpMethod, String params) throws IOException {
        // 设置参数
        StringEntity requestEntity = new StringEntity(params, Constant.DEFAULT_ENCODING);
        requestEntity.setContentEncoding(Constant.DEFAULT_ENCODING);
        httpMethod.setHeader("Content-type", "application/json");
        // 设置到请求的http对象中
        httpMethod.setEntity(requestEntity);
    }

    /**
     * Description: 设置参数
     * 
     * @param httpMethod
     * @param params 参数
     * @throws IOException
     */
    private void setParam(HttpEntityEnclosingRequestBase httpMethod, Map<String, String> params) throws IOException {
        // 设置参数
        if (isNotBlankObject(params)) {
            List<NameValuePair> nvps = new ArrayList<>();
            for (Entry<String, String> entry : params.entrySet()) {
                nvps.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
            }

            // 设置到请求的http对象中
            httpMethod.setEntity(new UrlEncodedFormEntity(nvps, HttpClientUtil.encoding));
        }
    }

    /**
     * Description: 获得响应结果
     * 
     * @param httpResponse
     * @param httpClient
     * @param httpMethod
     * @return
     * @throws IOException
     */
    private String getHttpClientResult(CloseableHttpResponse httpResponse, CloseableHttpClient httpClient,
        HttpRequestBase httpMethod) throws IOException {

        // 执行请求
        httpResponse = httpClient.execute(httpMethod);

        // 获取返回结果
        if (isNotBlankObjectListAll(httpResponse, httpResponse.getStatusLine())) {
            String content = "";
            if (isNotBlankObject(httpResponse.getEntity())) {
                content = EntityUtils.toString(httpResponse.getEntity(), HttpClientUtil.encoding);
            }
            httpMethod.releaseConnection();
            return content;
        }
        httpMethod.releaseConnection();
        return null;
    }

    /**
     * Description: 获得响应结果
     * 
     * @param httpResponse
     * @param httpClient
     * @param httpMethod
     * @return
     * @throws IOException
     */
    private byte[] getHttpClientByteResult(CloseableHttpResponse httpResponse, CloseableHttpClient httpClient,
        HttpRequestBase httpMethod) throws IOException {

        // 执行请求
        httpResponse = httpClient.execute(httpMethod);

        // 获取返回结果
        if (isNotBlankObjectListAll(httpResponse, httpResponse.getStatusLine())) {
            byte[] content = null;
            if (isNotBlankObject(httpResponse.getEntity())) {
                content = EntityUtils.toByteArray(httpResponse.getEntity());
            }
            httpMethod.releaseConnection();
            return content;
        }
        httpMethod.releaseConnection();
        return null;
    }

    /**
     * Description: 释放资源
     * 
     * @param httpResponse
     * @param httpClient
     * @throws IOException
     */
    private void release(CloseableHttpResponse httpResponse, CloseableHttpClient httpClient) throws IOException {
        // 释放资源
        if (isNotBlankObject(httpResponse)) {
            httpResponse.close();
        }
        if (isNotBlankObject(httpClient)) {
            httpClient.close();
        }
    }

    /**
     * 判断一个对象是否不是空(空对象)
     * 
     * @param obj
     * @return
     */
    private static boolean isBlankObject(Object obj) {
        return StringUtil.isBlankObject(obj);
    }

    /**
     * 判断一个对象是否不是空(空对象)
     * 
     * @param obj
     * @return
     */
    private boolean isNotBlankObject(Object obj) {
        return StringUtil.isNotBlankObject(obj);
    }

    /**
     * 一次性判断多个或单个对象不为空(空对象)
     * 
     * @param objects
     * @return 所有元素都不为Blank,则返回true
     */
    private boolean isNotBlankObjectListAll(Object... objs) {
        return StringUtil.isNotBlankObjectListAll(objs);
    }

    public static HttpClientUtilImpl getInstances() {
        if (isBlankObject(httpClientUtilsImpl)) {
            httpClientUtilsImpl = new HttpClientUtilImpl();
        }
        return httpClientUtilsImpl;
    }

}